package com.yaorange.module.security.service.impl;

import com.yaorange.container.PermissionContainer;
import com.yaorange.exception.BusinessException;
import com.yaorange.exception.ResourceNotFoundException;
import com.yaorange.ma_util.util.JwtUtil;
import com.yaorange.ma_util.util.Md5Util;
import com.yaorange.ma_util.util.ThreadLocalUtil;
import com.yaorange.module.security.dto.LoginDto;
import com.yaorange.module.security.service.AuthService;
import com.yaorange.module.security.vo.MenuVo;
import com.yaorange.module.security.vo.ResourceVo;
import com.yaorange.module.system.entity.vo.PermissionTreeVo;
import com.yaorange.module.system.service.SysPermissionService;
import com.yaorange.module.system.service.SysUserService;
import com.yaorange.pojo.SysPermission;
import com.yaorange.pojo.SysUser;
import com.yaorange.response.enums.ResultCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class AuthServiceImpl implements AuthService {
    @Autowired
    private SysPermissionService sysPermissionService;

    @Autowired
    PermissionContainer permissionContainer;

    @Autowired
    private SysUserService sysUserService;
    @Override
    public String login(LoginDto loginDto) {
        //查询用户是否存在
        SysUser user = sysUserService.findByUsername(loginDto.getUsername());
        if (user == null){
            throw new ResourceNotFoundException("用户名或密码错误");
        }
        //验证密码是否正确
        if (!Md5Util.md5(loginDto.getPassword()).equals(user.getUserPassword())){
            throw new ResourceNotFoundException("用户名或密码错误");
        }
        //生成token并返回
        Map<String,Object> claims = new HashMap<>();
        claims.put("userId",user.getUserId());
        claims.put("nickName",user.getUserNickname());
        claims.put("avatar",user.getUserAvatar());
        claims.put("admin",user.getAdmin());
        String token = JwtUtil.generateToken(claims);

        return token;
    }

    @Override
    public ResourceVo getResource() {
        HashMap map = ThreadLocalUtil.get();
        if (map == null){
            throw new BusinessException(ResultCode.FAIL);
        }
        Integer id = (Integer)map.get("userId");
//        Integer admin = (Integer)map.get("admin");
        List<SysPermission> permissionList =sysPermissionService.findPermissionTreeByUserId(id);
        List<SysPermission> allPermissionList = sysPermissionService.findPermissionList();
        ResourceVo resourceVo = builResourceVo(permissionList,allPermissionList);
        permissionContainer.put("LOGIN_USER_"+id.toString(),resourceVo.getPermissions());
        return resourceVo;
    }

    private ResourceVo builResourceVo(List<SysPermission> permissionList,List<SysPermission> allPermissionList) {
        ResourceVo resourceVo = new ResourceVo();
        Set<String> psSet = permissionList.stream().map(SysPermission::getPermExpression).filter(StringUtils::hasText).collect(Collectors.toSet());
        resourceVo.setPermissions(psSet);
        HashMap<Long, MenuVo> menuVoMap = new HashMap<>();
        for (SysPermission permission:allPermissionList) {
            MenuVo menuVo = new MenuVo();
            menuVo.setTitle(permission.getPermTitle());
            menuVo.setPath(permission.getPermPath());
            menuVo.setComponent(permission.getPermComponent());
            menuVo.setChildren(new ArrayList<>());
            menuVo.setType(permission.getPermType());
            menuVoMap.put(permission.getPermId(),menuVo);
        }
        Set<MenuVo> rootTreeVo = new HashSet<>();
        for (SysPermission permission : permissionList){
            if (null == permission.getPermPid() || 0 == permission.getPermPid()){

                MenuVo parentVo = menuVoMap.get(permission.getPermId());
                rootTreeVo.add(parentVo);
            }else {
                MenuVo parentVo = menuVoMap.get(permission.getPermPid());
                parentVo.getChildren().add(menuVoMap.get(permission.getPermId()));
//                if(!rootTreeVo.contains(parentVo)){
//                    rootTreeVo.add(parentVo);
//                }
//                Iterator<MenuVo> iterator = rootTreeVo.iterator();
//                while (iterator.hasNext()){
//                    String title = iterator.next().getTitle();
//                    if (!title.equals(parentVo.getTitle()) && !iterator.hasNext()){
//                        rootTreeVo.add(parentVo);
//                    }
//                }


            }
        }
        resourceVo.setMenus(rootTreeVo);
        return resourceVo;
    }
}
